package AttachmentService

import (
	"fmt"
	"gdshop-back-end-go/common/request/AttachmentReq"
	"gdshop-back-end-go/common/response"
	"gdshop-back-end-go/common/tools"
	"gdshop-back-end-go/common/tools/fileTypeTest"
	"github.com/gogf/gf/frame/g"
	"github.com/gogf/gf/net/ghttp"
	"github.com/gogf/gf/os/gfile"
	"github.com/gogf/gf/os/gtime"
	"github.com/gogf/gf/util/gconv"
	"github.com/gogf/gf/util/grand"
	"strings"
)

func MergeChunk(r *ghttp.Request) *response.JsonResponse {
	var parames *AttachmentReq.MergeChunk
	var err error
	ctx := r.GetCtx()
	if err = r.Parse(&parames); err != nil {
		return response.FailByRequestMessage(r, "合并失败："+err.Error())
	}
	score, err := getMemWithScore(ctx, parames.FileMd5)
	if err != nil {
		return response.FailByRequestMessage(r, "读取Redis失败："+err.Error())
	}
	// 判断是否上传完成
	if len(score) != parames.Chunks {
		return response.SuccessByRequestMessage(r, "分片未上传完成，总分片数："+gconv.String(parames.Chunks)+"，已上传分片数："+gconv.String(len(score)))
	}

	// 判断是否合并中
	isMerge, err := isMerging(ctx, parames.FileMd5)
	if err != nil {
		return response.FailByRequestMessage(r, "读取Redis失败："+err.Error())
	}
	if isMerge {
		return response.FailByRequestMessage(r, "合并中请稍等")
	}
	// 合并文件
	// 在Redis里面加锁
	err = setMerging(ctx, parames.FileMd5)
	if err != nil {
		return response.FailByRequestMessage(r, "读取Redis失败："+err.Error())
	}

	uploadChunkPath := g.Cfg().GetString("upload.UploadChunkPath")
	// 合并文件
	saveFilePreFix := g.Cfg().GetString("upload.WwwrootPath")
	url := "/upload/" + gtime.Now().Format("Ym") + "/" + gtime.Now().Format("d") + "/"
	fileExt := gfile.Ext(parames.Filename)
	fileName := grand.Letters(2) + grand.S(30) + fileExt
	newFileMd5, err := mergeFile(ctx, parames.FileMd5, uploadChunkPath, saveFilePreFix+url, fileName, parames.LastModified)
	if err != nil {
		return response.FailByRequestMessage(r, "上传失败："+err.Error())
	}
	if newFileMd5 != parames.FileMd5 {
		fmt.Println("文件MD5不一致 ", newFileMd5, parames.FileMd5)
		return response.FailByRequestMessage(r, "上传失败：文件MD5不一致")
	}

	// 删除合并信息
	err = deleteMerging(ctx, parames.FileMd5)
	if err != nil {
		return response.FailByRequestMessage(r, "上传失败："+err.Error())
	}
	// 删除分片信息
	pieceClaer(ctx, parames.FileMd5, uploadChunkPath)

	contentType, err := fileTypeTest.GetContentTypeByPath(saveFilePreFix + url + fileName)
	if err != nil {
		return response.FailByRequestMessage(r, err.Error())
	}
	// 添加数据到数据库
	insertData := g.Map{
		"original_name": parames.Filename,
		"save_name":     fileName,
		"save_path":     url,
		"url":           url + fileName,
		"extension":     strings.Trim(fileExt, "."),
		"mime":          contentType,
		"size":          parames.FileSize,
		"md5":           parames.FileMd5,
	}
	res := UploadAdd(r, insertData)
	if res.Code != 0 {
		return res
	}
	resData := gconv.Map(res.Data)
	insertData["id"] = resData["id"]
	PhotoPreFix := g.Cfg().GetString("upload.PhotoPreFix")
	insertData["base_url"] = PhotoPreFix
	insertData["icon"] = tools.GetIconByExtension(gconv.String(strings.Trim(fileExt, ".")))
	return response.SuccessByRequestMessageData(nil, "成功", insertData)
}
